package org.walkerljl.config.abstracts;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.walkerljl.config.Configurator;

/**
 * AbstractConfigurator
 * 
 * @author lijunlin
 */
public abstract class AbstractConfigurator implements Configurator {
	
	@Override
	public Byte getPropertyAsByte(String key) {
		return getPropertyAsByte(key, null);
	}
	
	@Override
	public Byte getPropertyAsByte(String key, Byte defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Byte.valueOf(value);
	}

	@Override
	public Short getPropertyAsShort(String key) {
		return getPropertyAsShort(key, null);
	}
	
	@Override
	public Short getPropertyAsShort(String key, Short defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Short.valueOf(value);
	}

	@Override
	public Integer getPropertyAsInteger(String key) {
		return getPropertyAsInteger(key, null);
	}
	
	@Override
	public Integer getPropertyAsInteger(String key, Integer defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Integer.valueOf(value);
	}

	@Override
	public Long getPropertyAsLong(String key) {
		return getPropertyAsLong(key, null);
	}
	
	@Override
	public Long getPropertyAsLong(String key, Long defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Long.valueOf(value);
	}

	@Override
	public Float getPropertyAsFloat(String key) {
		return getPropertyAsFloat(key, null);
	}
	
	@Override
	public Float getPropertyAsFloat(String key, Float defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Float.valueOf(value);
	}

	@Override
	public Double getPropertyAsDouble(String key) {
		return getPropertyAsDouble(key, null);
	}
	
	@Override
	public Double getPropertyAsDouble(String key, Double defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Double.valueOf(value);
	}

	@Override
	public Character getPropertyAsChar(String key) {
		return getPropertyAsChar(key, null);
	}
	
	@Override
	public Character getPropertyAsChar(String key, Character defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Character.valueOf(value.charAt(0));
	}

	@Override
	public Boolean getPropertyAsBoolean(String key) {
		return getPropertyAsBoolean(key, null);
	}
	
	@Override
	public Boolean getPropertyAsBoolean(String key, Boolean defaultValue) {
		String value = getPropertyAsString(key);
		return value == null ? defaultValue : Boolean.valueOf(value);
	}

	@Override
	public String getPropertyAsString(String key) {
		return getPropertyAsString(key, null);
	}

	@Override
	public String getPropertyAsString(String key, String defaultValue) {
		Object value = getProperty(wrapKey(key));
		return value == null ? defaultValue : value.toString();
	}

	@Override
	public String[] getPropertyAsStringArray(String key, String regex) {
		String value = getPropertyAsString(key);
		return value == null ? new String[0] : value.split(regex);
	}

	@Override
	public <T> List<T> getPropertyAsList(Class<T> type, String key, String regex) {
		String value = getPropertyAsString(key);
		List<T> items = new ArrayList<T>();
		if (value != null) {
			String[] array = value.split(regex);
			if (array != null && array.length != 0) {
				for (String item : array) {
					items.add(valueOf(type, item));
				}
			}
		}
		return items;
	}

	@Override
	public <T> Set<T> getPropertyAsSet(Class<T> type, String key, String regex) {
		String value = getPropertyAsString(key);
		Set<T> items = new HashSet<T>();
		if (value != null) {
			String[] array = value.split(regex);
			if (array != null && array.length != 0) {
				for (String item : array) {
					items.add(valueOf(type, item));
				}
			}
		}
		return items;
	}

	@Override
	public <T> Map<String, T> getPropertyAsMap(Class<T> type, String key, String regex, String entryRegex) {
		String value = getPropertyAsString(key);
		Map<String, T> map = new HashMap<String, T>();
		if (value != null) {
			String[] array = value.split(regex);
			if (array != null && array.length != 0) {
				for (String item : array) {
					String[] entry = item.split(entryRegex);
					if (entry != null && entry.length > 1) {
						map.put(entry[0], valueOf(type, entry[1]));
					}
				}
			}
		}
		return map;
	}

	/**
	 * 获取值
	 * @param type
	 * @param value
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private <T> T valueOf(Class<T> type, String value) {
		if (value == null || "".equals(value) || value.length() == 0) {
			return null;
		} else if (type == Byte.class) {
			return (T) Byte.valueOf(value);
		} else if (type == Short.class) {
			return (T) Short.valueOf(value);
		} else if (type == Character.class) {
			return (T) Character.valueOf(value.charAt(0));
		} else if (type == Integer.class) {
			return (T) Integer.valueOf(value);
		} else if (type == Long.class) {
			return (T) Long.valueOf(value);
		} else if (type == Float.class) {
			return (T) Float.valueOf(value);
		} else if (type == Double.class) {
			return (T) Double.valueOf(value);
		} else if (type == Boolean.class) {
			return (T) Boolean.valueOf(value);
		} else if (type == String.class) {
			return (T) value;
		} else {
			throw new RuntimeException("不支持此类型数据转换:" + type);
		}
	}
	
	@Override
	public Map<String, Object> getProperties() {
		throw new RuntimeException("不支持此方法的调用");
	}

	@Override
	public void setProperty(String key, Object value) {
		throw new RuntimeException("不支持此方法的调用");
	}
	
	@Override
	public void remove(String key) {
		throw new RuntimeException("不支持此方法的调用");
	}

	@Override
	public void clear() {
		throw new RuntimeException("不支持此方法的调用");
	}
	
	/**
	 * 包装Key,统一转换成小写的Key且trim前后空格
	 * @param key
	 * @return
	 */
	protected String wrapKey(String key) {
		return key == null ? null : key.trim().toLowerCase();
	}
}